import { memo, useCallback, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';

import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import TFMantineSearchableSelect from 'common/components/TFMantineSearchableSelect';

import { SelectItem } from '@mantine/core';
import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { modelSelected } from 'features/parameters/store/actions';
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
import { modelIdToMainModelParam } from 'features/parameters/util/modelIdToMainModelParam';
// import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { forEach } from 'lodash-es';
import {
  NON_SDXL_MAIN_MODELS,
  NON_REFINER_BASE_MODELS,
} from 'services/api/constants';
import { useGetMainModelsQuery } from 'services/api/endpoints/models';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';

const selector = createSelector(
  stateSelector,
  (state) => ({ model: state.generation.model }),
  defaultSelectorOptions
);

const ParamMainModelSelect = () => {
  const dispatch = useAppDispatch();
  const { t } = useTranslation();
  const isSDXLDisabled = useFeatureStatus('sdxl').isFeatureDisabled;

  const { model } = useAppSelector(selector);

  const { data: mainModels, isLoading } = useGetMainModelsQuery(
    isSDXLDisabled ? NON_SDXL_MAIN_MODELS : NON_REFINER_BASE_MODELS
  );

  const data = useMemo(() => {
    if (!mainModels) {
      return [];
    }

    const data: SelectItem[] = [];

    forEach(mainModels.entities, (model, id) => {
      if (!model) {
        return;
      }

      data.push({
        value: id,
        label: model.model_name,
        group: MODEL_TYPE_MAP[model.base_model],
      });
    });

    return data;
  }, [mainModels]);

  // grab the full model entity from the RTK Query cache
  // TODO: maybe we should just store the full model entity in state?
  const selectedModel = useMemo(
    () =>
      mainModels?.entities[`${model?.base_model}/main/${model?.model_name}`] ??
      null,
    [mainModels?.entities, model]
  );

  const handleChangeModel = useCallback(
    (v: string | null) => {
      if (!v) {
        return;
      }

      const newModel = modelIdToMainModelParam(v);

      if (!newModel) {
        return;
      }

      dispatch(modelSelected(newModel));
    },
    [dispatch]
  );

  useEffect(() => {
    if (!selectedModel && data[0]) {
      const newModel = modelIdToMainModelParam(data[0]?.value);
      newModel && dispatch(modelSelected(newModel));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data, dispatch]);

  return isLoading ? (
    <TFMantineSearchableSelect
      label={t('modelManager.model')}
      placeholder={`${t('modelManager.loading')}...`}
      disabled={true}
      data={[]}
    />
  ) : (
    <TFMantineSearchableSelect
      tooltip={selectedModel?.description}
      label={t('modelManager.model')}
      value={selectedModel?.id}
      placeholder={
        data.length > 0
          ? t('modelManager.selectAModel')
          : t('modelManager.noModelsAvailable')
      }
      data={data}
      error={data.length === 0}
      disabled={data.length === 0}
      onChange={handleChangeModel}
      w="100%"
    />
  );
};

export default memo(ParamMainModelSelect);
